#pragma once
#include "log.hpp"
#include "Socket.hpp"
#include "HttpRequest.hpp"
#include <thread>
#include <iostream>
#include <fstream>

#define PORT 9000

class HttpServer
{
public:
    HttpServer(uint16_t port = PORT) : _port(port) {}

    void startServer()
    {
        _sock.Socket();
        _sock.Bind(_port);
        _sock.Listen();

        for (;;) {
            string clientIp;
            uint16_t clientPort;
            int sockFd = _sock.Accept(&clientIp, &clientPort);
            log(INFO, "get a new link, fd: %d\n", sockFd);
            thread([=]
            {
                handlerHttp(sockFd);
            }).detach();
        }
    }

    // 获得请求，发送响应
    void handlerHttp(int sockFd)
    {
        char buf[10240];
        memset(buf, 0, sizeof buf);
        for(;;) {
            ssize_t n = read(sockFd, buf, sizeof buf);
            if (n > 0) {
                // 打印一下客户端的信息
                buf[n] = 0;
                cout << buf;
                // 自定义协议，获取路径
                HttpRequest req = HttpRequest();
                req.deserialize(buf);
                req.parseHeadLine();
                // req.printInfo();
                // string path = ROOTPATH;
                // path += url;
                // 返回响应
                string text = readFromHtml(req.filePath);
                string statusLine = "HTTP/1.1 200 OK\r\n";
                string header = "Content-Length: ";
                header += to_string(text.size()) + "\r\n";
                string blankLine = "\r\n";
                string response = (statusLine + header + blankLine + text);
                write(sockFd, response.c_str(), response.size());
            } else if (n==0) {
                cout << "read done\n";
                break;
            } else {
                cout << "read error!\n";
                break;
            } 
        }   
        close(sockFd);
    }

    // 读文件
    string readFromHtml(string path)
    {
        std::ifstream file(path);
        if(!file)   {
            log(FATAL, "readFromHtml() open error!\n");
            return "500";
        }

        std::string line = "";
        std::string content = "";
        while(getline(file, line)) {
            content += line;
        }
        return content;
    }
private:
    Sock _sock;
    uint16_t _port;
};